package com.zrrd.yt.product.service.impl;

import com.zrrd.yt.product.service.TestService;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;


/**
 * 案例需求：
 * 1、手动的在Redis中存入一个值  key=num  value=0
 * 2、收到请求后、查询redis中的num值
 * 查询到了：num+1 重新存入
 * 没有查到：结束该方法
 */
@Service
public class TestServiceImpl implements TestService {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RedissonClient redissonClient;

    @Override
    public void testLock() throws InterruptedException {
        //定义锁的key
        String skuId = "49";
        String lockKey = "lock:" + skuId;
        //获取锁对象
        RLock lock = redissonClient.getLock(lockKey);
        //上锁(使用可重入锁)
        lock.tryLock(100, 10, TimeUnit.SECONDS);
        //从redis中查询数据
        String value = redisTemplate.opsForValue().get("num");
        //非空判断
        if (StringUtils.isBlank(value)) {
            return;
        }
        //将字符串转为int
        int num = Integer.parseInt(value);
        //将num的值+1重新存入redis
        redisTemplate.opsForValue().set("num", (++num) + "");
        //解锁
        lock.unlock();
    }

    @Override
    public String readLock() {
        //获取读写锁对象
        RReadWriteLock readWriterLock = redissonClient.getReadWriteLock("readWriterLock");
        //通过读写锁对象获取读的锁
        RLock readLock = readWriterLock.readLock();
        //上锁
        readLock.lock(10, TimeUnit.SECONDS);
        //读取redis的数据
        String msg = redisTemplate.opsForValue().get("msg");
        //返回结果
        return msg;
    }

    @Override
    public String writeLock() {
        //获取读写锁对象
        RReadWriteLock readWriterLock = redissonClient.getReadWriteLock("readWriterLock");
        //获取写的锁
        RLock writeLock = readWriterLock.writeLock();
        //上锁
        writeLock.lock(10, TimeUnit.SECONDS);
        //向redis写入数据
        String uuid = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set("msg", uuid);
        return "写入成功==>" + uuid;
    }
}
